package com.ermax.aircond.manage.service;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ermax.aircond.common.dao.ReadMachineDataDao;
import com.ermax.aircond.common.domain.ReadMachineData;
import com.ermax.aircond.common.domain.WriteMachineData;
import com.ermax.aircond.common.parameter.Status;
import com.ermax.aircond.common.service.WriteMachineDataService;
import com.ermax.aircond.maintain.dao.MachineDao;
import com.ermax.aircond.maintain.domain.Machine;
import com.ermax.aircond.maintain.domain.Room;
import com.ermax.aircond.manage.domain.RealTimeControl;
import com.ermax.aircond.util.service.MachineCommandService;

@Service("realTimeControlService")
public class RealTimeControlService {

	private static Logger logger = LoggerFactory.getLogger(RealTimeControlService.class);

	@Resource(name = "machineDao")
	private MachineDao machineDao;
	@Resource(name = "readMachineDataDao")
	private ReadMachineDataDao readMachineDataDao;
	@Resource(name = "writeMachineDataService")
	private WriteMachineDataService writeMachineDataService;
	@Resource(name = "machineCommandService")
	private MachineCommandService machineCommandService;

	@Transactional
	public List<RealTimeControl> getRealTimeControls(Room room) throws Exception {
		List<RealTimeControl> results = new ArrayList<RealTimeControl>();
		List<Machine> machines = machineDao.findMachines(null, null, room, null, Status.ACTIVE);
		for (Machine machine : machines) {
			// read SDATA to get real time info
			int nid = machineCommandService.getNid(machine.getGateNo(), machine.getDeviceNo());
			ReadMachineData readMachineData = readMachineDataDao.findMachineDateByNid(nid);
			if (readMachineData != null) {
				List<String> values = machineCommandService.extractMachineData(readMachineData.getData());
				RealTimeControl realTimeControl = convert(machine, values);
				results.add(realTimeControl);
			}

		}
		return results;
	}

	@Transactional
	public List<RealTimeControl> getRealTimeControls(Machine machine) throws Exception {
		List<RealTimeControl> results = new ArrayList<RealTimeControl>();

		// read SDATA to get real time info
		int nid = machineCommandService.getNid(machine.getGateNo(), machine.getDeviceNo());
		ReadMachineData readMachineData = readMachineDataDao.findMachineDateByNid(nid);
		if (readMachineData != null) {
			List<String> values = machineCommandService.extractMachineData(readMachineData.getData());
			RealTimeControl realTimeControl = convert(machine, values);
			results.add(realTimeControl);
		}

		return results;
	}

	@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_SUPERVISOR')")
	public void sendRealTimeSignal(Room room, RealTimeControl realTimeControl) throws Exception {
		String cmd = convent(realTimeControl);

		List<Machine> machines = machineDao.findMachines(null, null, room, null, Status.ACTIVE);
		for (Machine machine : machines) {
			short nid = machineCommandService.getShortNid(machine.getGateNo(), machine.getDeviceNo());
			WriteMachineData writeMachineData = new WriteMachineData();
			writeMachineData.setNid(nid);

			writeMachineData.setCmd(cmd);
			logger.debug("Set command:" + nid + "," + cmd);
			writeMachineDataService.insertUpdate(writeMachineData);
		}
	}

	@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_SUPERVISOR')")
	public void sendRealTimeSignal(Machine machine, RealTimeControl realTimeControl) throws Exception {
		String cmd = convent(realTimeControl);

		short nid = machineCommandService.getShortNid(machine.getGateNo(), machine.getDeviceNo());
		WriteMachineData writeMachineData = new WriteMachineData();
		writeMachineData.setNid(nid);

		writeMachineData.setCmd(cmd);
		logger.debug("Set command:" + nid + "," + cmd);
		writeMachineDataService.insertUpdate(writeMachineData);

	}

	private String convent(RealTimeControl realTimeControl) {
		StringBuilder sb = new StringBuilder();

		sb.append(machineCommandService.getOnOffString(realTimeControl.isStart()));
		sb.append(machineCommandService.getFanSpeedString(realTimeControl.getFanSpeed()));
		sb.append(machineCommandService.getDefaultTempString(realTimeControl.getTemperature()));
		sb.append(machineCommandService.getKeyLockString(realTimeControl.getKeyLock()));
		sb.append(machineCommandService.getMinimumTempString(realTimeControl.getMinimumTemperature()));
		sb.append(machineCommandService.getValveOnOffString(1));
		// sb.append(machineCommandService.getValveLevelString(realTimeControl.getWindValue()));

		return machineCommandService.getCommandString(sb.toString());
	}

	private RealTimeControl convert(Machine machine, List<String> values) {
		RealTimeControl realTimeControl = new RealTimeControl();
		realTimeControl.setMachine(machine);
		for (String value : values) {
			/*
			 * String content = value.substring(1);
			 * 
			 * //啟停 A A0停 A1啟 if(value.startsWith("A")){
			 * if("1".equals(content)){ realTimeControl.setStart(true); }else{
			 * realTimeControl.setStart(false); } }
			 * 
			 * //風速 B B0自動 B1高 B2中 B3低 if(value.startsWith("B")){
			 * realTimeControl.setFanSpeed(content); }
			 * 
			 * //設定溫度 D D16~D32 if(value.startsWith("D")){
			 * realTimeControl.setTemperature(content); }
			 * 
			 * //風門開度 V V0~V100 if(value.startsWith("V")){
			 * realTimeControl.setWindValue(content); }
			 */
			logger.debug("command from db:" + value);
			realTimeControl = machineCommandService.translateCommand(realTimeControl, value);

		}

		return realTimeControl;
	}

}
